/**
  ******************************************************************************
  * @file    stm32f4xx_types.h
  * @author  MCD Application Team
  * @brief   Common types definitions for STM32F4xx.
  ******************************************************************************
  */

#ifndef __STM32F4xx_TYPES_H
#define __STM32F4xx_TYPES_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* IO definitions (access restrictions to peripheral registers) */
#define     __I     volatile const /*!< Defines 'read only' permissions */
#define     __O     volatile       /*!< Defines 'write only' permissions */
#define     __IO    volatile       /*!< Defines 'read / write' permissions */

/* Exported types ------------------------------------------------------------*/

/**
  * @brief  Functional State enumeration
  */
typedef enum {RESET = 0, SET = !RESET} FunctionalState;

/**
  * @brief  Flag Status enumeration
  */
typedef enum {Flag_RESET = 0, Flag_SET = !Flag_RESET} FlagStatus, ITStatus;

/**
  * @brief  Error Status enumeration
  */
typedef enum {SUCCESS = 0, ERROR = !SUCCESS} ErrorStatus;

/**
  * @brief  GPIO Type definitions
  */
typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,     Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register, Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register, Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register, Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register, Address offset: 0x14      */
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register, Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
} GPIO_TypeDef;

/**
  * @brief  SPI Type definitions
  */
typedef struct
{
  __IO uint32_t CR1;      /*!< SPI control register 1 (not used in I2S mode),      Address offset: 0x00 */
  __IO uint32_t CR2;      /*!< SPI control register 2,                                 Address offset: 0x04 */
  __IO uint32_t SR;       /*!< SPI status register,                                    Address offset: 0x08 */
  __IO uint32_t DR;       /*!< SPI data register,                                      Address offset: 0x0C */
  __IO uint32_t CRCPR;    /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */
  __IO uint32_t RXCRCR;   /*!< SPI RX CRC register (not used in I2S mode),          Address offset: 0x14 */
  __IO uint32_t TXCRCR;   /*!< SPI TX CRC register (not used in I2S mode),          Address offset: 0x18 */
  __IO uint32_t I2SCFGR;  /*!< SPI_I2S configuration register,                       Address offset: 0x1C */
  __IO uint32_t I2SPR;    /*!< SPI_I2S prescaler register,                           Address offset: 0x20 */
} SPI_TypeDef;

/* Memory mapping of STM32F4xx peripherals */
#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000)
#define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x10000000)

#define GPIOA_BASE            (AHB1PERIPH_BASE + 0x0000)
#define GPIOB_BASE            (AHB1PERIPH_BASE + 0x0400)
#define GPIOC_BASE            (AHB1PERIPH_BASE + 0x0800)
#define GPIOD_BASE            (AHB1PERIPH_BASE + 0x0C00)
#define GPIOE_BASE            (AHB1PERIPH_BASE + 0x1000)
#define GPIOF_BASE            (AHB1PERIPH_BASE + 0x1400)
#define GPIOG_BASE            (AHB1PERIPH_BASE + 0x1800)
#define GPIOH_BASE            (AHB1PERIPH_BASE + 0x1C00)
#define GPIOI_BASE            (AHB1PERIPH_BASE + 0x2000)

#define SPI1_BASE             (APB2PERIPH_BASE + 0x3000)
#define SPI2_BASE             (APB1PERIPH_BASE + 0x3800)
#define SPI3_BASE             (APB1PERIPH_BASE + 0x3C00)
#define SPI4_BASE             (APB2PERIPH_BASE + 0x3400)
#define SPI5_BASE             (APB2PERIPH_BASE + 0x5000)
#define SPI6_BASE             (APB2PERIPH_BASE + 0x15000)

#define RCC_BASE              (AHB1PERIPH_BASE + 0x3800)

/* Peripheral pointers */
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH               ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOI               ((GPIO_TypeDef *) GPIOI_BASE)

#define SPI1                ((SPI_TypeDef *) SPI1_BASE)
#define SPI2                ((SPI_TypeDef *) SPI2_BASE)
#define SPI3                ((SPI_TypeDef *) SPI3_BASE)
#define SPI4                ((SPI_TypeDef *) SPI4_BASE)
#define SPI5                ((SPI_TypeDef *) SPI5_BASE)
#define SPI6                ((SPI_TypeDef *) SPI6_BASE)

/* RCC Type definitions */
typedef struct
{
  __IO uint32_t CR;        /*!< RCC clock control register,                                  Address offset: 0x00 */
  __IO uint32_t PLLCFGR;   /*!< RCC PLL configuration register,                              Address offset: 0x04 */
  __IO uint32_t CFGR;      /*!< RCC clock configuration register,                             Address offset: 0x08 */
  __IO uint32_t CIR;       /*!< RCC clock interrupt register,                                 Address offset: 0x0C */
  __IO uint32_t AHB1RSTR;  /*!< RCC AHB1 peripheral reset register,                          Address offset: 0x10 */
  __IO uint32_t AHB2RSTR;  /*!< RCC AHB2 peripheral reset register,                          Address offset: 0x14 */
  __IO uint32_t AHB3RSTR;  /*!< RCC AHB3 peripheral reset register,                          Address offset: 0x18 */
  uint32_t      RESERVED0;  /*!< Reserved, 0x1C                                                                    */
  __IO uint32_t APB1RSTR;  /*!< RCC APB1 peripheral reset register,                          Address offset: 0x20 */
  __IO uint32_t APB2RSTR;  /*!< RCC APB2 peripheral reset register,                          Address offset: 0x24 */
  uint32_t      RESERVED1;  /*!< Reserved, 0x28                                                                    */
  uint32_t      RESERVED2;  /*!< Reserved, 0x2C                                                                    */
  __IO uint32_t AHB1ENR;   /*!< RCC AHB1 peripheral clock enable register,                  Address offset: 0x30 */
  __IO uint32_t AHB2ENR;   /*!< RCC AHB2 peripheral clock enable register,                  Address offset: 0x34 */
  __IO uint32_t AHB3ENR;   /*!< RCC AHB3 peripheral clock enable register,                  Address offset: 0x38 */
  uint32_t      RESERVED3;  /*!< Reserved, 0x3C                                                                    */
  __IO uint32_t APB1ENR;   /*!< RCC APB1 peripheral clock enable register,                  Address offset: 0x40 */
  __IO uint32_t APB2ENR;   /*!< RCC APB2 peripheral clock enable register,                  Address offset: 0x44 */
  uint32_t      RESERVED4;  /*!< Reserved, 0x48                                                                    */
  uint32_t      RESERVED5;  /*!< Reserved, 0x4C                                                                    */
  __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
  __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
  __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
  uint32_t      RESERVED6;  /*!< Reserved, 0x5C                                                                    */
  __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
  __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
  uint32_t      RESERVED7;  /*!< Reserved, 0x68                                                                    */
  uint32_t      RESERVED8;  /*!< Reserved, 0x6C                                                                    */
  __IO uint32_t BDCR;      /*!< RCC Backup domain control register,                          Address offset: 0x70 */
  __IO uint32_t CSR;       /*!< RCC clock control & status register,                         Address offset: 0x74 */
  uint32_t      RESERVED9;  /*!< Reserved, 0x78                                                                    */
  uint32_t      RESERVED10; /*!< Reserved, 0x7C                                                                    */
  __IO uint32_t SSCGR;     /*!< RCC spread spectrum clock generation register,               Address offset: 0x80 */
  __IO uint32_t PLLI2SCFGR;/*!< RCC PLLI2S configuration register,                          Address offset: 0x84 */
  __IO uint32_t PLLSAICFGR;/*!< RCC PLLSAI configuration register,                          Address offset: 0x88 */
  __IO uint32_t DCKCFGR;   /*!< RCC Dedicated Clocks configuration register,                 Address offset: 0x8C */
} RCC_TypeDef;

#define RCC                 ((RCC_TypeDef *) RCC_BASE)

/* IO definitions (access restrictions to peripheral registers) */
#define     __I     volatile const /*!< Defines 'read only' permissions */
#define     __O     volatile       /*!< Defines 'write only' permissions */
#define     __IO    volatile       /*!< Defines 'read / write' permissions */

/* Add必要的Class型定义 */
#define ENABLE                      ((FunctionalState)0x01)
#define DISABLE                     ((FunctionalState)0x00)

/* Add必要的宏定义 */
#define assert_param(expr) ((void)0)

#ifdef __cplusplus
}
#endif

#endif /* __STM32F4xx_TYPES_H */
